package com.automannn.atm_back.modules.codeGenerator.controller;

import com.automannn.atm_back.common.api.vo.Result;
import com.automannn.atm_back.common.system.vo.LoginUser;
import com.automannn.atm_back.modules.codeGenerator.core.pojo.ColumnConfig;
import com.automannn.atm_back.modules.codeGenerator.core.pojo.GlobalConfig;
import com.automannn.atm_back.modules.codeGenerator.core.pojo.Template;
import com.automannn.atm_back.modules.codeGenerator.core.service.CodeService;
import com.automannn.atm_back.modules.codeGenerator.core.service.CompressService;
import com.automannn.atm_back.modules.codeGenerator.core.util.FileUtils;
import com.automannn.atm_back.modules.codeGenerator.core.util.StringUtils;
import com.automannn.atm_back.modules.codeGenerator.entity.*;
import com.automannn.atm_back.modules.codeGenerator.service.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.shiro.SecurityUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/codeGenerate")
public class CodeGenerateController {

    @Resource
    private CodeService velocityCodeService;

    @Resource
    private ColumnConfigGroupEntityService columnConfigGroupEntityService;

    @Resource
    private ColumnConfigEntityService columnConfigEntityService;

    @Resource
    private TemplateEntityService templateEntityService;

    @Resource
    private TemplateGroupEntityService templateGroupEntityService;

    @Resource
    private GlobalConfigGroupEntityService globalConfigGroupEntityService;

    @Resource
    private GlobalConfigEntityService globalConfigEntityService;

    @Resource
    private CompressService compressService;

    @RequestMapping("/debug")
    /**
     * @param code 代码,必传
     * @param globalGroupId 模板宏,可选
     */
    public Result debug(String code, String columnConfigGroupId, String globalConfigGroupId) {
        if (StringUtils.isEmpty(code)) throw new RuntimeException("调试代码不能为空!");
        //1.选择数据源配置
        ColumnConfigGroupEntity columnConfigGroupEntity = columnConfigGroupEntityService.queryOne(columnConfigGroupId);
        if (columnConfigGroupEntity == null) {
            throw new RuntimeException("没找到数据源配置!");
        } else {
            ColumnConfigEntity columnConfigEntity = new ColumnConfigEntity();
            columnConfigEntity.setColumnConfigGroupId(columnConfigGroupId);
            List<ColumnConfigEntity> columnConfigEntityList = columnConfigEntityService.queryAll(new Page(), columnConfigEntity).getRecords();
            columnConfigGroupEntity.setColumnConfigEntityList(columnConfigEntityList);
        }
        //3.选择全局配置
        List<GlobalConfig> globalConfigList = null;
        if(!StringUtils.isEmpty(globalConfigGroupId)){
            GlobalConfigGroupEntity globalConfigGroupEntity = globalConfigGroupEntityService.queryOne(globalConfigGroupId);
            if (globalConfigGroupEntity == null) {
                throw new RuntimeException("没找到数据宏配置");
            }
            GlobalConfigEntity globalConfigEntity = new GlobalConfigEntity();
            globalConfigEntity.setGlobalConfigGroupId(globalConfigGroupEntity.getId());
            List<GlobalConfigEntity> globalConfigEntityList = globalConfigEntityService.queryAll(new Page(), globalConfigEntity).getRecords();
            //将 bean 实体转为 core的关键实体
            globalConfigList = globalConfigEntityList.stream().map(item -> item.toGlobalConfig()).collect(Collectors.toList());
        }
        Template template = new Template();
        template.setName("debug"+new Date().getTime());
        template.setCode(code);
        String codeResult = velocityCodeService.generate(template, columnConfigGroupEntity.toTableInfo(), globalConfigList);
        Result result = new Result();
        result.setResult(codeResult);
        return result;
    }

    @RequestMapping("/generate")
    public ResponseEntity generate(String templateGroupId, String columnConfigGroupId, String globalConfigGroupId) {
        //1.获取模板
        TemplateEntity templateEntityParam = new TemplateEntity();
        templateEntityParam.setTemplateGroupId(templateGroupId);
        List<TemplateEntity> list = templateEntityService.queryAll(new Page<>(1,-1),templateEntityParam).getRecords();
        if (list.size()==0) {
            throw new RuntimeException("没找到模板对象!");
        }
        //2.选择数据源配置
        ColumnConfigGroupEntity columnConfigGroupEntity = columnConfigGroupEntityService.queryOne(columnConfigGroupId);
        if (columnConfigGroupEntity == null) {
            throw new RuntimeException("没找到数据源配置!");
        } else {
            ColumnConfigEntity columnConfigEntity = new ColumnConfigEntity();
            columnConfigEntity.setColumnConfigGroupId(columnConfigGroupId);
            List<ColumnConfigEntity> columnConfigEntityList = columnConfigEntityService.queryAll(new Page(), columnConfigEntity).getRecords();
            columnConfigGroupEntity.setColumnConfigEntityList(columnConfigEntityList);
        }
        //3.选择全局配置
        GlobalConfigGroupEntity globalConfigGroupEntity = globalConfigGroupEntityService.queryOne(globalConfigGroupId);
        if (globalConfigGroupEntity == null) {
            throw new RuntimeException("没找到数据宏配置");
        }
        GlobalConfigEntity globalConfigEntity = new GlobalConfigEntity();
        globalConfigEntity.setGlobalConfigGroupId(globalConfigGroupEntity.getId());
        List<GlobalConfigEntity> globalConfigEntityList = globalConfigEntityService.queryAll(new Page(), globalConfigEntity).getRecords();

        //todo: 将shiro的认证换位springSecurity的授权
        //将 bean 实体转为 core的关键实体
        List<GlobalConfig> globalConfigList = globalConfigEntityList.stream().map(item -> item.toGlobalConfig()).collect(Collectors.toList());
        LoginUser loginUser= (LoginUser) SecurityUtils.getSubject().getPrincipal();


        String rootPath = compressService.getTmpDir() + "_"+loginUser.getUsername();
        if (rootPath.startsWith("/")) rootPath = rootPath.substring(1);
        if (!rootPath.endsWith("/")) rootPath = rootPath + "/";

        File oldFile = new File(rootPath);
        if (oldFile.exists()) {
            boolean deleteFlag = FileUtils.delete(rootPath);
            if (!deleteFlag) throw new RuntimeException("删除历史文件时出错，请联系管理员!");
        }
        //开始生成:
        list.forEach(item->{
            velocityCodeService.generate(item.toTemplate(), columnConfigGroupEntity.toTableInfo(), globalConfigList);
        });
       File file = compressService.compress();
       if (file.exists()) return export(file);
       else {
           throw new RuntimeException("文件不存在!");
       }

    }


    private ResponseEntity<FileSystemResource> export(File file) {
        if (file == null) {
            return null;
        }
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Content-Disposition", "attachment; filename=" + file.getName());
        headers.add("Access-Control-Expose-Headers", "Content-Disposition");
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        headers.add("Last-Modified", new Date().toString());
        headers.add("ETag", String.valueOf(System.currentTimeMillis()));
        return ResponseEntity.ok().headers(headers).contentLength(file.length()).contentType(MediaType.parseMediaType("application/octet-stream")).body(new FileSystemResource(file));
    }


}
